#include <ros/ros.h>
#include "fibonacci_action/fibonacciAction.h"
#include <actionlib/client/simple_action_client.h>

typedef actionlib::SimpleActionClient<fibonacci_action::fibonacciAction> Client;

void done_callback(const actionlib::SimpleClientGoalState& state, const fibonacci_action::fibonacciResultConstPtr& result)
{
    switch(state.state_)
    {
        case actionlib::SimpleClientGoalState::SUCCEEDED:
            ROS_INFO("SUCCEEDED!!!!");
            break;
        case actionlib::SimpleClientGoalState::ABORTED:
            ROS_INFO("ABORTED!!!!");
            break;
        case actionlib::SimpleClientGoalState::PREEMPTED:
            ROS_INFO("PREEMPTED!!!!");
            break;
        default:
            break;
    }
}


void feedback_callback(const fibonacci_action::fibonacciFeedbackConstPtr& feedback)
{
    static double pre_back_num = 1;
    for(const auto &s: feedback->sequence)
    {
        printf("%d ", s);
    }
    printf("\r\n");

    // ROS_INFO("Ratio= %f", (double)feedback->sequence.back()/ pre_back_num); //数越大越接近黄金分割比1:0.618
    // pre_back_num = feedback->sequence.back();
}

void active_call_back()
{
    ROS_INFO("ACTIVE");
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "fibonacci_action");
    Client client("/fibonacci_action", true); // true -> don't need ros::spin()

    client.waitForServer();
    fibonacci_action::fibonacciGoal goal;
    goal.order = 20;
    client.sendGoal(goal, boost::bind(&done_callback, _1, _2), 
                                    boost::bind(&active_call_back), 
                                    boost::bind(&feedback_callback, _1));
    
    client.waitForResult(ros::Duration(100.0));
    if(client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
    {
        ROS_INFO("Generate Success!");
    }
    ROS_INFO("Current State: %s\n", client.getState().toString().c_str());
    return 0;
}